import math
import numpy as np
from scipy import signal
import copy
import pyqtgraph as pg
import pyqtgraph.exporters
import binascii

# tab2的波形窗口,leftButtonPan=False表示鼠标不能拖动，靠矩形窗放大
pg.setConfigOptions(leftButtonPan=True, antialias=True)
# https://www.runoob.com/w3cnote/ascii.html


def data_process_fun(data_list, time_list, symbol_T, sample_rate, threshold, C_or_P_Flag):
    """
    将实际接收到的数据处理
    :param data_list: 从csv文件中读取的电压值序列[列表]
    :param time_list: 从csv文件中读取的时间序列[列表]
    :param symbol_T: 一个符号持续的时间(亮’1‘的时长)
    :param sample_rate: 采样频率
    :param threshold: 人为设定的电压判决阈值
    :param C_or_P_Flag: 通信或定位，通信时2个峰，定位时8个峰
    :return error_rate: 误码率
    :return bin_code: 解调(解PPM)结果[列表]
    :return output: 解码结果(用户输入)[字符串]
    """
    # "1"亮时长(s)
    T = symbol_T
    # 采样周期Ts(s)
    Ts = 1 / sample_rate
    # csv中的时间序列t
    t = time_list
    # 阈值
    the_threshold = threshold
    v = data_list
    # 阈值判决
    v1 = [1 if i >= the_threshold else -1 for i in v]

    # 巴克码的横坐标t_bark(s)
    num_points_bark = int(13 * T / Ts)
    t_bark = np.linspace(0.0, 13 * T, num_points_bark, dtype='float')
    Code = 0. * t_bark
    per_points = int(T / Ts)
    Code[0: 5 * per_points - 1] = 1
    Code[5 * per_points: 7 * per_points - 1] = -1
    Code[7 * per_points: 9 * per_points - 1] = 1
    Code[9 * per_points: 10 * per_points - 1] = -1
    Code[10 * per_points: 11 * per_points - 1] = 1
    Code[11 * per_points: 12 * per_points - 1] = -1
    Code[12 * per_points: 13 * per_points - 1] = 1

    # 重采样，线性插值
    num_points_data = int(t[-1] / Ts)
    t_inter = np.linspace(t[0], t[-1], num_points_data, dtype='float')
    v1_inter = np.interp(t_inter, t, v1)

    c = signal.fftconvolve(Code, v1_inter[::-1], 'full')
    lags = signal.correlation_lags(len(Code), len(v1_inter))

    # 取两个最大的互相关值分别作为帧头帧尾
    v_max = np.max(c)
    idx = np.argmax(c)
    # 找第二个最大值, 将第一个最大值附近（范围约为1次巴克码持续时间）的值设为0
    c_copy = copy.deepcopy(c)  # !!!!! 不能直接=赋值，用=是对象引用，得用deepcopy()进行深度拷贝
    c_copy[idx - int(13 * T / Ts / 2): idx + int(13 * T / Ts / 2)] = 0
    v_max_2 = np.max(c_copy)
    idx_2 = np.argmax(c_copy)

    if C_or_P_Flag == 0:
        # 通信，一组巴克码，2个峰
        v_array = np.array([v_max, v_max_2])
        idx_array = np.array([idx, idx_2])
    else:
        # 定位，4组巴克码，8个峰
        # 找第3~8个峰
        c_copy_3 = copy.deepcopy(c_copy)  # 用于找第3个峰
        c_copy_3[idx_2 - int(13 * T / Ts / 2): idx_2 + int(13 * T / Ts / 2)] = 0
        v_max_3 = np.max(c_copy_3)
        idx_3 = np.argmax(c_copy_3)

        c_copy_4 = copy.deepcopy(c_copy_3)  # 用于找第4个峰
        c_copy_4[idx_3 - int(13 * T / Ts / 2): idx_3 + int(13 * T / Ts / 2)] = 0
        v_max_4 = np.max(c_copy_4)
        idx_4 = np.argmax(c_copy_4)

        c_copy_5 = copy.deepcopy(c_copy_4)  # 用于找第5个峰
        c_copy_5[idx_4 - int(13 * T / Ts / 2): idx_4 + int(13 * T / Ts / 2)] = 0
        v_max_5 = np.max(c_copy_5)
        idx_5 = np.argmax(c_copy_5)

        c_copy_6 = copy.deepcopy(c_copy_5)  # 用于找第6个峰
        c_copy_6[idx_5 - int(13 * T / Ts / 2): idx_5 + int(13 * T / Ts / 2)] = 0
        v_max_6 = np.max(c_copy_6)
        idx_6 = np.argmax(c_copy_6)

        c_copy_7 = copy.deepcopy(c_copy_6)  # 用于找第7个峰
        c_copy_7[idx_6 - int(13 * T / Ts / 2): idx_6 + int(13 * T / Ts / 2)] = 0
        v_max_7 = np.max(c_copy_7)
        idx_7 = np.argmax(c_copy_7)

        c_copy_8 = copy.deepcopy(c_copy_7)  # 用于找第8个峰
        c_copy_8[idx_7 - int(13 * T / Ts / 2): idx_7 + int(13 * T / Ts / 2)] = 0
        v_max_8 = np.max(c_copy_8)
        idx_8 = np.argmax(c_copy_8)

        v_array = np.array([v_max, v_max_2, v_max_3, v_max_4, v_max_5, v_max_6, v_max_7, v_max_8])
        idx_array = np.array([idx, idx_2, idx_3, idx_4, idx_5, idx_6, idx_7, idx_8])

    # idx排序，idx越大，时间延迟越小，即时间上信号越早发出
    sorted_index = np.argsort(-idx_array)    # 加负号，idx由大到小排序
    idx_sorted = idx_array[sorted_index].tolist()
    v_max_sorted = v_array[sorted_index].tolist()

    lags = list(lags)

    # 画出互相关结果
    # 将互相关索引转为时间轴
    lags_t = copy.deepcopy(t_inter).tolist()
    lags_t = lags_t[::-1]
    lags_t = [-1*x for x in lags_t]
    temp = t_bark.tolist()[1:]
    lags_t = lags_t + temp

    star_idx = [lags_t[i] for i in idx_sorted]  # 用于画"*"的idx和v
    star_v = copy.deepcopy(v_max_sorted)
    p1 = pg.plot(lags_t, c, pen=pg.mkPen('#e4d94c', width=1))
    points = pg.ScatterPlotItem(star_idx, star_v, size=20, brush=pg.mkBrush(255, 83, 112, 255), symbol='star')
    p1.addItem(points)

    # 互相关的两个峰值加上标签
    text_1 = pg.TextItem(
        html='<div style="text-align: center"><span style="color: #FFF;">t = {0:.4} s</span></div>'.format(lags_t[idx]),
        anchor=(-0.1, 1))
    p1.addItem(text_1)
    text_1.setPos(lags_t[idx], v_max)

    text_2 = pg.TextItem(
        html='<div style="text-align: center"><span style="color: #FFF;">t = {0:.4} s</span></div>'.format(lags_t[idx_2]),
        anchor=(-0.1, 1))
    p1.addItem(text_2)
    text_2.setPos(lags_t[idx_2], v_max_2)

    if C_or_P_Flag == 1:
        # 定位8个峰，添加剩余6个的时间标签
        try:
            text_3 = pg.TextItem(
                html='<div style="text-align: center"><span style="color: #FFF;">t = {0:.4} s</span></div>'.format(
                    lags_t[idx_3]),
                anchor=(-0.1, 1))
            p1.addItem(text_3)
            text_3.setPos(lags_t[idx_3], v_max_3)
            text_4 = pg.TextItem(
                html='<div style="text-align: center"><span style="color: #FFF;">t = {0:.4} s</span></div>'.format(
                    lags_t[idx_4]),
                anchor=(-0.1, 1))
            p1.addItem(text_4)
            text_4.setPos(lags_t[idx_4], v_max_4)
            text_5 = pg.TextItem(
                html='<div style="text-align: center"><span style="color: #FFF;">t = {0:.4} s</span></div>'.format(
                    lags_t[idx_5]),
                anchor=(-0.1, 1))
            p1.addItem(text_5)
            text_5.setPos(lags_t[idx_5], v_max_5)
            text_6 = pg.TextItem(
                html='<div style="text-align: center"><span style="color: #FFF;">t = {0:.4} s</span></div>'.format(
                    lags_t[idx_6]),
                anchor=(-0.1, 1))
            p1.addItem(text_6)
            text_6.setPos(lags_t[idx_6], v_max_6)
            text_7 = pg.TextItem(
                html='<div style="text-align: center"><span style="color: #FFF;">t = {0:.4} s</span></div>'.format(
                    lags_t[idx_7]),
                anchor=(-0.1, 1))
            p1.addItem(text_7)
            text_7.setPos(lags_t[idx_7], v_max_7)
            text_8 = pg.TextItem(
                html='<div style="text-align: center"><span style="color: #FFF;">t = {0:.4} s</span></div>'.format(
                    lags_t[idx_8]),
                anchor=(-0.1, 1))
            p1.addItem(text_8)
            text_8.setPos(lags_t[idx_8], v_max_8)
        except:
            pass

    labelStyle = {'color': '#fafafa', 'font-size': '10pt'}
    p1.setLabel("left", "互相关值", **labelStyle)
    p1.setLabel("bottom", "时间(s)", **labelStyle)
    p1.showGrid(x=True, y=True, alpha=0.5)  # 显示表格线
    p1.setBackground('#373741')
    exporter = pg.exporters.ImageExporter(p1.plotItem)
    exporter.parameters()['width'] = 1920  # (note this also affects height parameter)
    # exporter.parameters()['height'] = 1080
    exporter.export('./Cross_correlation_result.png')

    idx_delay_list = [len(t_inter) - x for x in idx_sorted]  # 采样数据时间轴上的帧头帧尾成对出现

    # 画帧头帧尾区域
    p2 = pg.plot(t_inter, v1_inter, pen=pg.mkPen('#e4d94c', width=1))
    p2.setZValue(1)

    region_1 = pg.LinearRegionItem()
    region_1.setRegion([t_inter[idx_delay_list[0]], t_inter[idx_delay_list[0] + int(13 * T/Ts)]])
    region_1.setBrush(pg.mkColor(255, 83, 112, 80))
    p2.addItem(region_1, ignoreBounds=True)

    region_2 = pg.LinearRegionItem()
    region_2.setRegion([t_inter[idx_delay_list[1]], t_inter[idx_delay_list[1] + int(13 * T / Ts)]])
    region_2.setBrush(pg.mkColor(255, 83, 112, 80))
    p2.addItem(region_2, ignoreBounds=True)
    
    if C_or_P_Flag == 1:
        # 定位，画剩余3组帧头帧尾区域
        region_3 = pg.LinearRegionItem()
        region_3.setRegion([t_inter[idx_delay_list[2]], t_inter[idx_delay_list[2] + int(13 * T / Ts)]])
        region_3.setBrush(pg.mkColor(255, 83, 112, 80))
        p2.addItem(region_3, ignoreBounds=True)

        region_4 = pg.LinearRegionItem()
        region_4.setRegion([t_inter[idx_delay_list[3]], t_inter[idx_delay_list[3] + int(13 * T / Ts)]])
        region_4.setBrush(pg.mkColor(255, 83, 112, 80))
        p2.addItem(region_4, ignoreBounds=True)

        region_5 = pg.LinearRegionItem()
        region_5.setRegion([t_inter[idx_delay_list[4]], t_inter[idx_delay_list[4] + int(13 * T / Ts)]])
        region_5.setBrush(pg.mkColor(255, 83, 112, 80))
        p2.addItem(region_5, ignoreBounds=True)

        region_6 = pg.LinearRegionItem()
        region_6.setRegion([t_inter[idx_delay_list[5]], t_inter[idx_delay_list[5] + int(13 * T / Ts)]])
        region_6.setBrush(pg.mkColor(255, 83, 112, 80))
        p2.addItem(region_6, ignoreBounds=True)

        region_7 = pg.LinearRegionItem()
        region_7.setRegion([t_inter[idx_delay_list[6]], t_inter[idx_delay_list[6] + int(13 * T / Ts)]])
        region_7.setBrush(pg.mkColor(255, 83, 112, 80))
        p2.addItem(region_7, ignoreBounds=True)

        region_8 = pg.LinearRegionItem()
        region_8.setRegion([t_inter[idx_delay_list[7]], t_inter[idx_delay_list[7] + int(13 * T / Ts)]])
        region_8.setBrush(pg.mkColor(255, 83, 112, 80))
        p2.addItem(region_8, ignoreBounds=True)

    labelStyle = {'color': '#fafafa', 'font-size': '10pt'}
    p2.setLabel("left", "电压(V)", **labelStyle)
    p2.setLabel("bottom", "时间(s)", **labelStyle)
    p2.showGrid(x=True, y=True, alpha=0.5)  # 显示表格线
    p2.setBackground('#373741')

    exporter = pg.exporters.ImageExporter(p2.plotItem)
    exporter.parameters()['width'] = 1920  # (note this also affects height parameter)
    # exporter.parameters()['height'] = 1080
    exporter.export('./Frame_head&end.png')

    # # 解码
    output = []
    v2 = list(v1_inter[idx_delay_list[0]: idx_delay_list[1]])  # 拷贝帧头和帧尾之间的数据至v2（包括帧头）
    output.append(Binary_decode(v2, T, Ts))
    if C_or_P_Flag == 1:
        v2_2 = list(v1_inter[idx_delay_list[2]: idx_delay_list[3]])
        v2_3 = list(v1_inter[idx_delay_list[4]: idx_delay_list[5]])
        v2_4 = list(v1_inter[idx_delay_list[6]: idx_delay_list[7]])  # _4四帧内容
        output.append(Binary_decode(v2_2, T, Ts))
        output.append(Binary_decode(v2_3, T, Ts))
        output.append(Binary_decode(v2_4, T, Ts))
    return output


def Binary_decode(v2: list, T, Ts) -> list:
    """
    根据能量值判断符号是0还是1
    :param v2: 映射到01的帧内容，一维列表
    :param T: 符号周期
    :param Ts: 采样周期
    :return: Binary_list: 一维列表
    """
    v2 = [0 if i < 0 else i for i in v2]  # 将-1、1映射到0、1
    # 计算v2中含有的最大符号周期数
    num_symbol_T = int(math.floor(len(v2) / (T / Ts)))
    v2 = v2[0: int(num_symbol_T * T / Ts)]  # num_symbol_T取floor则去掉v2最后的一个符号
    # 根据符号周期数来划分时间段
    v3 = np.array(v2).reshape(num_symbol_T, int(T / Ts))

    # 一个'1'符号半个周期内的能量 = T / 2 * fs
    E_T_half = T / 2 / Ts

    # 对v3逐行(逐个符号)判决是比特0还是比特1
    # v3 = v3. ^ 2 # 可忽略，因为v1阈值判决后v3元素就只有0和1
    v3_E = list(np.sum(v3, axis=1))  # 计算每个符号周期内的能量值

    Binary_list = [1 if i >= E_T_half else 0 for i in v3_E]
    return Binary_list


def bits_to_PPM(bits_array):
    """
    bits映射到PPM
    :param bits_array: N*1个bit组成的一维列表
    :return: PPM_code: 2N*1的一维列表
    """
    len_serial = len(bits_array)
    bits_array = np.array(bits_array)
    bits_parallel = bits_array.reshape((int(len_serial / 2), 2))
    PPM_2d = []
    for i in range(int(len_serial / 2)):
        if (bits_parallel[i] == [0, 0]).all():
            PPM_2d.append([1, 0, 0, 0])
        elif (bits_parallel[i] == [0, 1]).all():
            PPM_2d.append([0, 1, 0, 0])
        elif (bits_parallel[i] == [1, 0]).all():
            PPM_2d.append([0, 0, 1, 0])
        elif (bits_parallel[i] == [1, 1]).all():
            PPM_2d.append([0, 0, 0, 1])
    PPM_code = [x for item in PPM_2d for x in item]
    return PPM_code


# 目前措施：如果接收到的数据不是4的倍数，向上取4的倍数
def PPM_to_bits(PPM_array):
    """
    PPM映射回bits
    :param PPM_array: 2N*1个PPM调制后比特组成的一维列表
    :return: bits_code: N*1的一维列表
    """
    len_serial = len(PPM_array)
    num_symbol = int(math.ceil(len_serial / 4))
    PPM_array = PPM_array + [0] * (num_symbol * 4 - len_serial)  # 补零成4的倍数
    PPM_array = np.array(PPM_array)
    bits_parallel = PPM_array.reshape((num_symbol, 4))
    bits_2d = []
    for i in range(num_symbol):
        if (bits_parallel[i] == [1, 0, 0, 0]).all():
            bits_2d.append([0, 0])
        elif (bits_parallel[i] == [0, 1, 0, 0]).all():
            bits_2d.append([0, 1])
        elif (bits_parallel[i] == [0, 0, 1, 0]).all():
            bits_2d.append([1, 0])
        elif (bits_parallel[i] == [0, 0, 0, 1]).all():
            bits_2d.append([1, 1])
        else:
            # 以上四种情况都不符合，那就是传输或者检测错误，暂设置为反映射为00
            bits_2d.append([0, 0])
    PPM_code = [x for item in bits_2d for x in item]
    return PPM_code


def input_to_PPMcode(input_s):
    """
    将用户输入的字符串转为PPM
    :param input_s:str类型
    :return: PPM_str str
    """
    input_encode = input_s.encode('utf-8')
    input_hex = input_encode.hex()  # bytes型转16进制
    ascii_list = []
    for i in range(int(len(input_hex) / 2)):
        now_ascii = int((input_hex[2 * i] + input_hex[2 * i + 1]), 16)
        ascii_list.append('{:08b}'.format(now_ascii))
    input_format = "".join(ascii_list)
    bin_list = [[int(bit) for bit in input_format]]
    PPM_list = bits_to_PPM(bin_list[0])
    PPM_list_char = [[str(bit) for bit in PPM_list]]
    PPM_str = '1111100110101' + ''.join(PPM_list_char[0]) + '11111001101010'
    # print(''.join(PPM_list_char[0]))
    return PPM_str


def PPMcode_to_output(PPMcode):
    """
    将接收到的PPM解调解码至字符串
    :param PPMcode: list类型
    :return: output str
    """
    # PPM_list = [int(bit) for bit in PPMcode][13:]  # 去掉帧头的13位巴克码
    PPM_list = PPMcode[13:]  # 去掉帧头的13位巴克码
    bin_list = PPM_to_bits(PPM_list)

    num_ascii = math.floor(len(bin_list)/8)  # 判断最少有多少个ASCii码,宁缺毋滥
    bytes_list = []
    for i in range(num_ascii):
        # 每8bits转为一个byte
        now_ascii_list = bin_list[8*i: 8*i+8]
        now_ascii_list = [str(x) for x in now_ascii_list]
        now_ascii_str = ''.join(now_ascii_list)
        now_hex_str = hex(int(now_ascii_str, 2))[2::]  # 去掉开头表示16进制的0x
        now_bytes_str = binascii.unhexlify(now_hex_str)
        bytes_list.append(now_bytes_str)

    idx_now = 0
    output_list = []
    while idx_now < len(bytes_list):
        # 判断是否有中文(3bytes)
        if bytes_list[idx_now].isascii():
            # 如果属于ASCii，直接单个解码
            output_list.append(bytes_list[idx_now].decode('utf-8', errors='replace'))
            idx_now = idx_now + 1
        else:
            # 如果是中文字符或非法字符
            if (idx_now+2) < len(bytes_list):
                char_123 = bytes_list[idx_now] + bytes_list[idx_now+1] + bytes_list[idx_now+2]
                idx_now = idx_now+3
                output_list.append(char_123.decode('utf-8', errors='replace'))
            else:
                # 非法字符
                output_list.append(bytes_list[idx_now].decode('utf-8', errors='replace'))
                idx_now = idx_now + 1

    output = ''.join(output_list)

    return output


def data_process_for_r(data_list, time_list, symbol_T, sample_rate, threshold, C_or_P_Flag):
    """
    将实际接收到的数据处理
    :param data_list: 从csv文件中读取的电压值序列[列表]
    :param time_list: 从csv文件中读取的时间序列[列表]
    :param symbol_T: 一个符号持续的时间(亮’1‘的时长)
    :param sample_rate: 采样频率
    :param threshold: 人为设定的电压判决阈值
    :param C_or_P_Flag: 通信或定位，通信时2个峰，定位时8个峰
    :return error_rate: 误码率
    :return bin_code: 解调(解PPM)结果[列表]
    :return output: 解码结果(用户输入)[字符串]
    """
    # "1"亮时长(s)
    T = symbol_T
    # 采样周期Ts(s)
    Ts = 1 / sample_rate
    # csv中的时间序列t
    t = time_list
    # 阈值
    the_threshold = threshold
    v = data_list
    # 阈值判决
    v1 = [1 if i >= the_threshold else -1 for i in v]

    # 巴克码的横坐标t_bark(s)
    num_points_bark = int(13 * T / Ts)
    t_bark = np.linspace(0.0, 13 * T, num_points_bark, dtype='float')
    Code = 0. * t_bark
    per_points = int(T / Ts)
    Code[0: 5 * per_points - 1] = 1
    Code[5 * per_points: 7 * per_points - 1] = -1
    Code[7 * per_points: 9 * per_points - 1] = 1
    Code[9 * per_points: 10 * per_points - 1] = -1
    Code[10 * per_points: 11 * per_points - 1] = 1
    Code[11 * per_points: 12 * per_points - 1] = -1
    Code[12 * per_points: 13 * per_points - 1] = 1

    # 重采样，线性插值
    num_points_data = int(t[-1] / Ts)
    t_inter = np.linspace(t[0], t[-1], num_points_data, dtype='float')
    v1_inter = np.interp(t_inter, t, v1)

    # 重采样，线性插值，不经过阈值判决
    num_points_data_nothreshold = int(t[-1] / Ts)
    t_inter_nothreshold = np.linspace(t[0], t[-1], num_points_data_nothreshold, dtype='float')
    v1_inter_nothreshold = np.interp(t_inter_nothreshold, t, v)

    c = signal.fftconvolve(Code, v1_inter[::-1], 'full')
    lags = signal.correlation_lags(len(Code), len(v1_inter))

    # 取两个最大的互相关值分别作为帧头帧尾
    v_max = np.max(c)
    idx = np.argmax(c)
    # 找第二个最大值, 将第一个最大值附近（范围约为1次巴克码持续时间）的值设为0
    c_copy = copy.deepcopy(c)  # !!!!! 不能直接=赋值，用=是对象引用，得用deepcopy()进行深度拷贝
    c_copy[idx - int(13 * T / Ts / 2): idx + int(13 * T / Ts / 2)] = 0
    v_max_2 = np.max(c_copy)
    idx_2 = np.argmax(c_copy)

    if C_or_P_Flag == 0:
        # 通信，一组巴克码，2个峰
        v_array = np.array([v_max, v_max_2])
        idx_array = np.array([idx, idx_2])
    else:
        # 定位，4组巴克码，8个峰
        # 找第3~8个峰
        c_copy_3 = copy.deepcopy(c_copy)  # 用于找第3个峰
        c_copy_3[idx_2 - int(13 * T / Ts / 2): idx_2 + int(13 * T / Ts / 2)] = 0
        v_max_3 = np.max(c_copy_3)
        idx_3 = np.argmax(c_copy_3)

        c_copy_4 = copy.deepcopy(c_copy_3)  # 用于找第4个峰
        c_copy_4[idx_3 - int(13 * T / Ts / 2): idx_3 + int(13 * T / Ts / 2)] = 0
        v_max_4 = np.max(c_copy_4)
        idx_4 = np.argmax(c_copy_4)

        c_copy_5 = copy.deepcopy(c_copy_4)  # 用于找第5个峰
        c_copy_5[idx_4 - int(13 * T / Ts / 2): idx_4 + int(13 * T / Ts / 2)] = 0
        v_max_5 = np.max(c_copy_5)
        idx_5 = np.argmax(c_copy_5)

        c_copy_6 = copy.deepcopy(c_copy_5)  # 用于找第6个峰
        c_copy_6[idx_5 - int(13 * T / Ts / 2): idx_5 + int(13 * T / Ts / 2)] = 0
        v_max_6 = np.max(c_copy_6)
        idx_6 = np.argmax(c_copy_6)

        c_copy_7 = copy.deepcopy(c_copy_6)  # 用于找第7个峰
        c_copy_7[idx_6 - int(13 * T / Ts / 2): idx_6 + int(13 * T / Ts / 2)] = 0
        v_max_7 = np.max(c_copy_7)
        idx_7 = np.argmax(c_copy_7)

        c_copy_8 = copy.deepcopy(c_copy_7)  # 用于找第8个峰
        c_copy_8[idx_7 - int(13 * T / Ts / 2): idx_7 + int(13 * T / Ts / 2)] = 0
        v_max_8 = np.max(c_copy_8)
        idx_8 = np.argmax(c_copy_8)

        v_array = np.array([v_max, v_max_2, v_max_3, v_max_4, v_max_5, v_max_6, v_max_7, v_max_8])
        idx_array = np.array([idx, idx_2, idx_3, idx_4, idx_5, idx_6, idx_7, idx_8])

    # idx排序，idx越大，时间延迟越小，即时间上信号越早发出
    sorted_index = np.argsort(-idx_array)  # 加负号，idx由大到小排序
    idx_sorted = idx_array[sorted_index].tolist()
    v_max_sorted = v_array[sorted_index].tolist()

    idx_delay_list = [len(t_inter) - x for x in idx_sorted]  # 采样数据时间轴上的帧头帧尾成对出现
    v2 = [[], [], [], []]  # 二维列表, 存4个帧头的数据
    v2[0] = list(
        v1_inter_nothreshold[idx_delay_list[0]: idx_delay_list[0] + (int(5 * T / Ts))])  # 拷贝未阈值判决的信号帧头前5个符号周期的11111\
    v2[1] = list(v1_inter_nothreshold[idx_delay_list[2]: idx_delay_list[2] + (int(5 * T / Ts))])
    v2[2] = list(v1_inter_nothreshold[idx_delay_list[4]: idx_delay_list[4] + (int(5 * T / Ts))])
    v2[3] = list(v1_inter_nothreshold[idx_delay_list[6]: idx_delay_list[6] + (int(5 * T / Ts))])

    z = [0, 0, 0, 0]
    for i in range(4):
        # 换算成OPT的输出电压v_real
        v_real = [(v * 100 * 2 / 255 - 1) * 5 for v in v2[i]]
        # 开方后求均值，得sqrt(功率)
        v_square = [v**0.5 for v in v_real]
        z[i] = ((sum(v_square)) / len(v_square))

    return z
